using System.Linq;
using Common.Commands;
using Common.Commands.ContactCommands;
using Core.Domain.Model;
using Core.Infrastructure.CustomExceptions;
using Sanelib.Common.Helpers;
using Sanelib.DataOperation;
using Sanelib.Dto;

namespace Core.Processors.ContactProcessors
{
    public class UpdateContactProcessor : ICommandProcessor<UpdateContact>
    {
        private readonly IRepository<Contact> _contactRepository;

        public UpdateContactProcessor(IRepository<Contact> contactRepository)
        {
            _contactRepository = contactRepository;
        }

        public dynamic Process(UpdateContact command)
        {
            var response = new WebApiResultResponse();

            EnsureSameNameContact(command);
            EnsureSameEmailContact(command);

            var contact = _contactRepository.GetById(command.Id);

            contact.Name = command.Name;
            contact.LastName = command.LastName;
            contact.FirstName = command.FirstName;
            contact.NameTitle = command.NameTitle;
            contact.Email = command.Email;
            contact.Phone = command.Phone;
            contact.Mobile = command.Mobile;
            contact.CompanyName = command.CompanyName;
            contact.Designation = command.Designation;
            contact.Description = command.Description;
            contact.ImageData = command.ImageData;
            contact.ModifiedBy = command.UserId;

            _contactRepository.Update(contact);

            response.IsSuccess = true;

            return response;
        }

        private void EnsureSameNameContact(UpdateContact command)
        {
            var alradyAddedContact = _contactRepository.GetAllFor(Property.Of<Contact>(x => x.Name), command.Name).SingleOrDefault();

            if (alradyAddedContact == null || alradyAddedContact.Id == command.Id) return;
            throw new DomainProcessException(string.Format("Contact Name should not be duplicated. Already available contact with this name : {0}", command.Name));
        }

        private void EnsureSameEmailContact(UpdateContact command)
        {
            var alradyAddedContactWithSameEmail = _contactRepository.GetAllFor(Property.Of<Contact>(x => x.Email), command.Email).SingleOrDefault();

            if (alradyAddedContactWithSameEmail == null || alradyAddedContactWithSameEmail.Id == command.Id) return;
            throw new DomainProcessException(string.Format("Contact Email should not be duplicated. Already available contact with this name : {0}", command.Name));
        }
    }
}
